import { Response } from 'express';
import { AuthHandler } from '../middleware/asyncHandler';
import { Errors } from '../types/errors';
import { logger } from '../utils/logger';
import AuditLog, { AuditLogType, AuditLogDocument } from '../models/auditLog';
import { AuditLogService } from '../services/auditLogService';
import { 
  AuditLogQuery, 
  AuditLogResponse,
  AuditLogFilters 
} from '../types/audit';

// === Helper Functions ===
function hasAdminAccess(user: { role: string }): boolean {
  return user.role === 'admin';
}

function buildFilters(query: AuditLogQuery, user: { _id: string; role: string }): AuditLogFilters {
  const filters: AuditLogFilters = {};

  // Type filter
  if (query.type && Object.values(AuditLogType).includes(query.type)) {
    filters.type = query.type;
  }

  // Date range filter
  if (query.startDate || query.endDate) {
    filters.timestamp = {};
    if (query.startDate) {
      filters.timestamp.$gte = new Date(query.startDate);
    }
    if (query.endDate) {
      filters.timestamp.$lte = new Date(query.endDate);
    }
  }

  // Resource filters
  if (query.resourceType) {
    filters.resourceType = query.resourceType;
  }
  if (query.resourceId) {
    filters.resourceId = query.resourceId;
  }

  // Status filter
  if (query.status) {
    filters.status = query.status;
  }

  // User filter - non-admins can only see their own logs
  if (!hasAdminAccess(user)) {
    filters.userId = user._id;
  } else if (query.userId) {
    filters.userId = query.userId;
  }

  return filters;
}

// === Controller Methods ===
export class AuditLogController {
  /**
   * 获取审计日志列表
   */
  static getAll: AuthHandler<{}, AuditLogResponse, {}, AuditLogQuery> = async (req, res) => {
    const page = parseInt(req.query.page || '1');
    const limit = parseInt(req.query.limit || '20');
    const skip = (page - 1) * limit;

    const filters = buildFilters(req.query, req.user);

    logger.debug('获取审计日志', {
      filters,
      page,
      limit,
      userId: req.user._id
    });

    const [logs, total] = await Promise.all([
      AuditLog.find(filters)
        .sort({ timestamp: -1 })
        .skip(skip)
        .limit(limit)
        .populate('userId', 'name email'),
      AuditLog.countDocuments(filters)
    ]);

    res.json({
      success: true,
      data: {
        logs,
        total,
        page,
        totalPages: Math.ceil(total / limit),
        hasMore: page * limit < total
      }
    });
  };

  /**
   * 获取单个审计日志
   */
  static getOne: AuthHandler<{ id: string }> = async (req, res) => {
    const log = await AuditLog.findById(req.params.id)
      .populate('userId', 'name email');

    if (!log) {
      throw Errors.notFound('审计日志不存在');
    }

    // Check access permission
    if (!hasAdminAccess(req.user) && log.userId.toString() !== req.user._id) {
      throw Errors.forbidden('无权访问此审计日志');
    }

    res.json({
      success: true,
      data: log
    });
  };

  /**
   * 获取审计日志统计信息
   */
  static getStats: AuthHandler = async (req, res) => {
    if (!hasAdminAccess(req.user)) {
      throw Errors.forbidden('只有管理员可以查看统计信息');
    }

    const stats = await AuditLogService.getStats();

    res.json({
      success: true,
      data: stats
    });
  };

  /**
   * 清理旧的审计日志
   */
  static cleanupLogs: AuthHandler = async (req, res) => {
    if (!hasAdminAccess(req.user)) {
      throw Errors.forbidden('只有管理员可以清理日志');
    }

    const { days = 30, types } = req.body;
    const result = await AuditLogService.cleanup(days, types);

    res.json({
      success: true,
      data: {
        deletedCount: result.deletedCount
      }
    });
  };

  /**
   * 创建审计日志
   */
  static create: AuthHandler<{}, AuditLogDocument> = async (req, res) => {
    if (!hasAdminAccess(req.user)) {
      throw Errors.forbidden('只有管理员可以手动创建审计日志');
    }

    const log = await AuditLogService.create({
      ...req.body,
      userId: req.user._id,
      ip: req.ip,
      userAgent: req.headers['user-agent']
    });

    res.status(201).json({
      success: true,
      data: log
    });
  };
}
